using System;
using System.Collections.Generic;
using System.Text;
using System.Transactions;
using NUnit.Framework;
using Hermes.Framework;
using Hermes.Framework.FileSystem;
using Hermes.Framework.Implementation;

namespace Hermes.Framework.Test
{
    [TestFixture]
    public class SimpleIntegerateTest
    {
        protected ITransactableOperationAbstractFactory transactOperationFactory = null;

        INonTransactableFileSystemFactory fileSystemFactory = null;

        protected IResourceManager resourceManager = null;

        string from = @"file://C:\Users\Sam\Documents\Visual Studio 2005\Projects\Hermes Framework\Hermes.Framework.Test\Resources\source.txt";
        string to = @"file://C:\Users\Sam\Documents\Visual Studio 2005\Projects\Hermes Framework\Hermes.Framework.Test\Resources\To\source.txt";
        string deleteFile = @"file://C:\Users\Sam\Documents\Visual Studio 2005\Projects\Hermes Framework\Hermes.Framework.Test\Resources\tobedeleted.txt";

        string ftpTo = @"ftp://localhost/source.txt";
        string ftpDelete = @"ftp://localhost/delete.txt";

        public SimpleIntegerateTest()
        {
            transactOperationFactory = new SimpleTransactionOperationAbstractFactory();
            transactOperationFactory.FileSystemFactory = fileSystemFactory;
            transactOperationFactory.ResourceManager = this.resourceManager;
        }

        public void Dispose()
        {

        }

        [SetUp]
        public void SetUp()
        {
            INonTransactableFileSystem fileSystem = this.fileSystemFactory.GetFileSystem(deleteFile);
            if (!fileSystem.Exists(deleteFile))
            {
                fileSystem.CreateFile(deleteFile);
            }
        }

        [TearDown]
        public void TearDown()
        {
            INonTransactableFileSystem fileSystem = this.fileSystemFactory.GetFileSystem(to);
            if (!fileSystem.Exists(to))
            {
                fileSystem.Delete(to);
            }
        }

        [Test]
        public void TestSuccess()
        {
            ExecuteTransaction(from, to, deleteFile);

            INonTransactableFileSystem fileSystemTo = this.fileSystemFactory.GetFileSystem(to);
            INonTransactableFileSystem fileSystemDelete = this.fileSystemFactory.GetFileSystem(deleteFile);

            if (!fileSystemTo.Exists(to) || fileSystemDelete.Exists(deleteFile))
            {
                Console.WriteLine("Transaction was incomplete.");
            }
            else
            {
                Console.WriteLine("Transaction is completed.");
            }
        }

        [Test]
        public void TestFail()
        {
            INonTransactableFileSystem fileSystem = this.fileSystemFactory.GetFileSystem(deleteFile);
            fileSystem.Delete(deleteFile);

            ExecuteTransaction(from, to, deleteFile);

            INonTransactableFileSystem fileSystemTo = this.fileSystemFactory.GetFileSystem(to);
            if (!fileSystemTo.Exists(to))
            {
                Console.WriteLine("Transaction is incomplete.");
            }
            else
            {
                Console.WriteLine("Transaction is completed.");
            }
        }

        protected void ExecuteTransaction(string from, string to, string deleteFile)
        {
            try
            {
                using (TransactionScope scope = new TransactionScope())
                {
                    ITransactableCopy copy = transactOperationFactory.GetCopy(from, to);
                    copy.Copy();

                    ITransactableDelete delete = transactOperationFactory.GetDelete(deleteFile);
                    delete.Delete();

                    scope.Complete();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                Console.WriteLine("Transaction rollbacked.");
            }
        }
    }
}
